/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package es.unavarra.mti.iws.logic.properties;

import es.unavarra.mti.iws.Manager;
import es.unavarra.mti.iws.logic.undoredo.SetProperty;
import es.unavarra.mti.iws.utils.ReflectionUtils;
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;

/**
 *
 * @author Asier
 */
public class PropertiesTableModel extends AbstractTableModel{
    private Manager manager;
    private final ArrayList<KProperty> properties;
    private final ArrayList<HasProperties> subjects;

    private static final String[] columnNames = {"Nombre", "Valor"};
    private static final Class[] columnTypes = {String.class,String.class};

    public PropertiesTableModel(Manager manager) {
        this.manager = manager;
        properties = new ArrayList<KProperty>();
        subjects = new ArrayList();
    }

    private void clear(){
        synchronized(properties){
            synchronized(subjects){
                subjects.clear();
                int size = properties.size();
                if(size > 0){
                    properties.clear();
                    fireTableRowsDeleted(0, size-1);
                }
            }
        }
    }

    public void refresh(){
        synchronized(properties){
            int size = properties.size();
            if(size > 0){
                fireTableRowsUpdated(0, size-1);
            }
        }
    }

    public void setSelection(List<? extends HasProperties> s) {
        clear();
        synchronized (subjects) {
            synchronized (properties) {
                if (s != null && !s.isEmpty()) {
                    Class t = maxCommonClass(s);
                    List<KProperty> listOfProperties = s.get(0).objectProperties(t);
                    subjects.addAll(s);
                    if (!listOfProperties.isEmpty()) {
                        if (subjects.size() == 1) {
                            properties.addAll(listOfProperties);
                        } else {
                            for (KProperty p : listOfProperties) {
                                if (p.isGroupable()) {
                                    properties.add(p);
                                }
                            }
                        }
                    }
                    if(!properties.isEmpty()){
                        fireTableRowsInserted(0, properties.size()-1);
                    }
                }
            }
        }
    }


    public int getColumnCount() {
        return columnNames.length;
    }

    public int getRowCount() {
       synchronized(properties){
            return properties.size();
       }
    }

    public Object getValueAt(int row, int column) {
       KProperty property = properties.get(row);
       if(column == 0){
           return property.getName();
       }else if(column == 1){
           synchronized(subjects){
                return property.getValue(subjects);
           }
       }
       return null;
    }

    @Override
    public Class getColumnClass(int c) {
        return columnTypes[c];
    }

    @Override
    public String getColumnName(int col) {
        return columnNames[col];
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        if (columnIndex == 1) { return true; }
        return false;
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        if(columnIndex != 1) {return;}
        KProperty property = properties.get(rowIndex);
        if ( ReflectionUtils.isSimpleType( property.getType()) ){
                Object newObject = ReflectionUtils.stringToSimpleObject(property.getType(), aValue.toString());
                SetProperty setOp = new SetProperty(this, subjects, property, newObject);
                manager.getUndo().addOp(setOp);
                setOp.redo();
                fireTableCellUpdated(rowIndex, columnIndex);
        }
        
    }


     private Class maxCommonClass(List<? extends HasProperties> objects) {
        if (objects == null || objects.isEmpty()) {
            return null;
        }
        Class maxCommonClass = objects.get(0).getClass();
        for (HasProperties ko : objects) {
            Class currentClass = ko.getClass();
            while (!maxCommonClass.isAssignableFrom(currentClass)) {
                maxCommonClass = maxCommonClass.getSuperclass();
            }
        }
        return maxCommonClass;
    }


}
